using System;
using System.Diagnostics;
using System.Collections;
using System.IO;


using CIndicators;
using CStock;
using CUtil;
using System.Data;
using CUtil.Excel;
using System.Collections.Generic;

namespace CStock
{
    /// <summary>
    /// Summary description for TradeSimulation.
    /// </summary>
    public class TradeSimulation : StockObjectBase, ITradeSimulation
    {
        #region private properties

        public TradeCSVOutputOptions TradeCSVOutputOptions;
        private string stringDelimiter = ";";

        public System.Collections.ArrayList portfolioOptimizationResultsCollection;

        

        private IGrid gridTrade;
        private static IProgramContext programContext;
        private ITrader trader;
        private ITradeSystem tradeSystem;
        //private ITradeStep tradeStep;
        //private ITradeStep tradeStepPortfolio;
        private static System.Collections.ArrayList tradeSystems;

        private static ITradeSystem tradeSystemForShortSell;

        private NameObjectCollection tradeOrders;

        //private IDataItem gridDataItem;
        ExcelWriter excelWriterOptimization;
        DataTable dataTableOptimization;
        private IList<IOptimizationResult> optimisationResultList;
        ITradeStep tradeStepActive;

        #endregion

        #region constructor, dispose


        public TradeSimulation(ITrader trad)
        {
            //this.Intraday = false;
            trader = trad;
            this.tradeOrders = new NameObjectCollection();

            TradeCSVOutputOptions = new TradeCSVOutputOptions();


        }
       

        public bool ResetPortfolioOptimization(IPortfolio myPortfolio)
        {
            //set the one and single optimzation result collection
            portfolioOptimizationResultsCollection = new System.Collections.ArrayList();
            IDataItem oldSelection = myPortfolio.DataItem_Selected;
            
            for (int i = 0; i < myPortfolio.DataItems.Count; i++)
            {
                IDataItem myDataItem = myPortfolio.DataItems[i];

                //myDataItem.DataClass = myDataItem.TradeStep.Portfolio.DataItems[i].DataClass;
                FirstInit_Optimize(myDataItem, myPortfolio, false);

            }
            myPortfolio.DataItem_Selected = oldSelection;

            return true;


        }
        ///// <summary>
        ///// 
        ///// </summary>
        ///// <param name="dt"></param>
        ///// <returns></returns>
        //private int SetShareSimulationToDate(IDataItem mydataItem, bool inOptimizationStep, DateTime dt)
        //{
        //    //

        //    mydataItem.TradeStep.IndicatorsString = "";//
        //    TradeStepFactory.Reset_Share_ForSimulation(mydataItem, this.tradeSystem, inOptimizationStep, 
        //        TradeSimulation.ProgramContext.Configuration.TradeMoneyType, Intraday);


        //    mydataItem.TradeStep.Date = dt;
        //    DateTime firstDate = mydataItem.DataClass.DateOf(0);
        //    int i = DateTime.Compare(mydataItem.TradeStep.Date, firstDate);
        //    return i;

        //}



        #endregion

        #region properties

        public override string ID
        {
            get
            {

                return this.iD;
            }
            set
            {
                this.iD = value;
                if (this.iD != null && this.iD != string.Empty)
                {
                    this.path = TradeSimulation.ProgramContext.Path + "\\TradeSimulations";
                    
                }
            }
        }

        #endregion

        #region implementations


   



        #endregion

        #region public properties

        /// <summary>
        /// 
        /// </summary>
        public void ResetIndicators(IDataItem myDataItem)
        {
            //IListQuotes qColl =  myDataItem.DataClass.QuoteCollection;
            //if(qColl != null && qColl.Count > 0)
            //{
            if (myDataItem.DataClass.IndicatorsJustGetEm != null)
            {
                myDataItem.DataClass.IndicatorsJustGetEm.Reset();
            }
            //}
        }


        /// <summary>
        /// 
        /// </summary>
        public bool Intraday
        {
            get
            {
                return TradeSimulation.ProgramContext.Configuration.IntradayModus;
            }


        }
        public IGrid GridTrade
        {
            get
            {
                return this.gridTrade;
            }
            set
            {
                this.gridTrade = value;
            }
        }
      



   


     

        #endregion

        #region public available methods




        public void PrognosisPortfolio(IPortfolio myPortfolio, DateTime myDate, int myTradeSystemIndex)
        {

            myPortfolio.TradeStepPortfolio.Date = myDate;
            //SetAndCheckDate();
            myPortfolio.TradeStepPortfolio.TradeSystemIndex = myTradeSystemIndex;

            PrognosisPortfolio(myPortfolio);

        }
        /// <summary>
        /// PrognosisPortfolio
        /// </summary>
        public void PrognosisPortfolio(IPortfolio myPortfolio)
        {

            for (int i = 0; i < myPortfolio.DataItems.Count; i++)
            {
                
                IDataItem myDataItem = myPortfolio.DataItems[i];


                myPortfolio.TradeStepPortfolio.DataItem_SelectedForPortfolio = myPortfolio.DataItems[i] as IDataItem;
                DataClass.DeSerialize(myDataItem.DataClass, this.Intraday);
                myPortfolio.TradeStepPortfolio.Date = myPortfolio.TradeStepPortfolio.Date;

                SetAndCheckDate(myDataItem);
                myPortfolio.TradeStepPortfolio.TradeSystemIndex = myDataItem.DataClass.IndexFindSmallerThanStartEnd(myDataItem.TradeStep.Date);
                
                

                if (myDataItem.TradeStep.TradeSystemIndex > -1)
                {

                    PrognosisShare(myDataItem);
                    ResetIndicators(myDataItem);
                }
            }

        }

    

        public void PrognosisPortfolioAdvanced(IPortfolio myPortfolio)
        {


            for (int i = 0; i < myPortfolio.DataItems.Count; i++)
            {
                
                IDataItem myDataItem = myPortfolio.DataItems[i];
                DataClass.DeSerialize(myDataItem.DataClass, this.Intraday);
                myDataItem.DataClass.Get_Indicators_ForTradeSystem(true, myDataItem.TradeStep.TradeSystem);



                PrognosisShareAdvanced(myDataItem);


            }
        }


        public double PrognosisShareAdvanced( IDataItem myDataItem,  DateTime myDate)
        {

            myDataItem.TradeStep.Date = myDate;
            SetAndCheckDate(myDataItem);
            return PrognosisShareAdvanced(myDataItem);

        }
        public double PrognosisShareAdvanced(IDataItem myDataItem)
        {

            //myDataItem.TradeStep = myDataItem.TradeStep.Portfolio.DataItems[i] as IDataItem;
            myDataItem.DataClass.DeSerialize();
            myDataItem.TradeStep.DateIndex = myDataItem.DataClass.QuoteCollection.IndexOf(myDataItem.TradeStep.Date);

            if (myDataItem.TradeStep.DateIndex < 0)
            {
                //we have only values from later than this date !
                //Debug.Assert(false,"Error getting the date index for date : " + myDate.ToShortDateString() + " and share " + myDataItem.DataClass.Name);
                myDataItem.TradeStep.PrognosisAll = null;
                if (this.gridTrade != null)
                    this.gridTrade.AddRow_Single(myDataItem.TradeStep, false);

              

                return -999;
            }
            else
            {
                myDataItem.TradeStep.PrognosisAll = new System.Collections.ArrayList();
                ArrayList tradeSystems = TradeSimulation.TradeSystemsAvailable;

                for (int i = 0; i < tradeSystems.Count; i++)
                {
                    myDataItem.TradeStep.TradeSystemIndex = i;
                    this.tradeSystem = tradeSystems[i] as ITradeSystem;

                    myDataItem.DataClass.Get_Indicators_ForTradeSystem(true, myDataItem.TradeStep.TradeSystem);

                    


                    PrognosisTradeSystemForDateIndex(myDataItem);

                    myDataItem.TradeStep.PrognosisAll.Add(myDataItem.TradeStep.Prognosis);




                }
               

            }
            return 0;

        }


        private double PrognosisShare(IDataItem myDataItem)
        {
            myDataItem.TradeStep.DateIndex = myDataItem.DataClass.IndexFindSmallerThanStartEnd(myDataItem.TradeStep.Date);
            //CalculateQuote();
            if (myDataItem.TradeStep.DateIndex < 0)
            {
                //we have only values from later than this date !
                //Debug.Assert(false,"Error getting the date index for date : " + myDate.ToShortDateString() + " and share " + myDataItem.DataClass.Name);
                if (this.gridTrade != null)
                    this.gridTrade.AddRow_Single(myDataItem.TradeStep, false);
                return -999;
            }
            else
            {
                //NameObjectCollection coll = TradeSystemStaticFunctions.GetIndicatorValues(myDataItem.TradeStep.DateIndex, myDataItem.TradeStep.TradeSystem, myDataItem.DataClass, this.Intraday);
                
                return myDataItem.TradeStep.Prognosis;

            }
        }

        private static void SetAndCheckDate(IDataItem myDataItem)
        {
            IListQuotes qColl = myDataItem.DataClass.QuoteCollection;

            if (myDataItem.TradeStep.Date > qColl[qColl.Count - 1].DATE)
            {
                myDataItem.TradeStep.Date = qColl[qColl.Count - 1].DATE;
            }
        }
        public double PrognosisShare(IDataItem myDataItem, DateTime myDate, int myTradeSystemIndex)
        {


            myDataItem.TradeStep.Date = myDate;
            SetAndCheckDate(myDataItem);

            myDataItem.TradeStep.Prognosis = 0;
            myDataItem.TradeStep.TradeSystemIndex = myTradeSystemIndex;



            return PrognosisShare(myDataItem);


        }

        private void PrognosisTradeSystemForDateIndex(IDataItem myDataItem)
        {
            if (myDataItem.TradeStep.DateIndex > (myDataItem.DataClass.QuoteCollection.Count - 1))
                return;
            myDataItem.TradeStep.TradeWriteMode = TradeWriteModes.EachTradeStep;

            Debug.Assert(myDataItem.DataClass.IndicatorsUnchecked != null);
            myDataItem.TradeStep.BuySellOccurs = TradeSystemStaticFunctions.Static_BuyCondition( myDataItem.TradeStep, myDataItem.TradeStep.TradeSystem);

           
            if (myDataItem.TradeStep.BuySellOccurs)
            {
                //str = myDataItem.TradeStep.IndicatorsString;
                myDataItem.TradeStep.Prognosis = 1000;
                //myDataItem.TradeStep.Prognosis calculated , also myDataItem.TradeStep.BuySellOccurs;
                //yeah - buy signal
            }
            else
            {

                myDataItem.TradeStep.TradeWriteMode = TradeWriteModes.EachTradeStep;
                myDataItem.TradeStep.BuySellOccurs = TradeSystemStaticFunctions.Static_SellCondition
                    ( myDataItem.TradeStep , this.TradeSystem);

                //str = myDataItem.TradeStep.IndicatorsString;
                if (myDataItem.TradeStep.BuySellOccurs)
                {
                    myDataItem.TradeStep.Prognosis = -1000;
                    myDataItem.TradeStep.BuySellOccurs = false;
                    //myDataItem.TradeStep.Prognosis and myDataItem.TradeStep.BuySellOccurs calculated
                    //yeah - buy signal
                }

            }


            if (myDataItem.TradeStep.Date.Equals(null))
            {
                myDataItem.TradeStep.Date = ((IQuote)myDataItem.DataClass.QuoteCollection[myDataItem.TradeStep.DateIndex]).DATE;
            }
            return;

        }

        #endregion


        #region Optimize
        public bool WriteSingleTradeResult(IDataItem myDataItem, IPortfolio myPortfolio, bool myWriteOption, bool inOptimizationLoop)
        {

            if (myWriteOption)
            {
                myDataItem.TradeStep.Date = myDataItem.TradeStep.DateMax;
                myDataItem.TradeStep.DateIndex = myDataItem.TradeStep.DateMaxIndex;


                TradeSystemStaticFunctions.SetTradeConditionsInTradeStep(myDataItem.TradeStep, myDataItem.TradeStep.TradeSystem);

                TradeStepFactory.EndEvaluations(myDataItem.TradeStep, Intraday);
                if (this.gridTrade != null)
                    this.gridTrade.AddRow_Single(myDataItem.TradeStep, false);

                if(! inOptimizationLoop)
                    Write_Simulation_CSV(myDataItem, myPortfolio, inOptimizationLoop);
                //trade step is reset by this


            }
            return true;
        }
     

        private bool CheckSimulationStartConditions( IDataItem myDataItem, bool inOptimizationLoop, TradeWriteModes myTradeMode)
        {
            
            TradeStepFactory.Reset_Share_ForSimulation(myDataItem, this.tradeSystem, inOptimizationLoop,
                TradeSimulation.ProgramContext.Configuration.TradeMoneyType, Intraday);

           
            myDataItem.TradeStep.TradeWriteMode = myTradeMode;
            return true;

        }
        public bool SimulationShare(IDataItem myDataItem,    TradeWriteModes myTradeMode, bool myWriteOption, bool inOptimizationLoop, IGrid myGrid)
        {
            try
            {
                if (myDataItem == null)
                    return false;

                TradeSimulation.ProgramContext.Logfile.WriteTimeLog(" ... Simulate share: " + myDataItem.DataClass.Name);

                if (!CheckSimulationStartConditions(myDataItem, inOptimizationLoop, myTradeMode))
                    return false;


                for (int i = myDataItem.TradeStep.DateMinIndex; i < myDataItem.TradeStep.DateMaxIndex; i++)
                {
                    TradeStepFactory.StepShare(myDataItem, myGrid, Intraday);
                    myDataItem.TradeStep.DateIndex++;

                }
                switch (myTradeMode)
                {
                    case TradeWriteModes.EndResultShare:
                        {
                            WriteSingleTradeResult(myDataItem, null, myWriteOption, inOptimizationLoop);
                            //write also in Excel File
                            Write_Simulation_CSV(myDataItem, null, inOptimizationLoop);
                            break;
                        }
                    case TradeWriteModes.OnlyTrade:
                        {

                            Write_Simulation_CSV(myDataItem, null, inOptimizationLoop);
                            break;
                        }
                }

              
               
                return true;
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error in SimulationShare ; " + ex.Message);
                return false;
            }
        }

        private void SimulationShareForOptimization( IDataItem myDataItem,  TradeWriteModes myTradeMode, bool WriteSimulationResult, IGrid myGrid)
        {

            SimulationShare(myDataItem, myTradeMode, WriteSimulationResult, true, myGrid);
            SetOptimizationResult(myDataItem, null);
        }

        public bool FirstInit_Optimize(IDataItem myDataItem,IPortfolio myPortfolio,  bool IsDataClass)
        {
            if (IsDataClass)
            {
                myDataItem.TradeStep.TradeSystem = this.tradeSystem;
                myDataItem.TradeStep.TradeWriteMode = TradeWriteModes.EndResultShare;
                TradeStepFactory.FirstInit_TradeStep(myDataItem, this.tradeSystem);
                myDataItem.TradeStep.TradeSystem.OptimizationResults = new List<IOptimizationResult>();


            }
            else
            {
                myPortfolio.TradeStepPortfolio.TradeWriteMode = TradeWriteModes.EndResultShare;
                //TradeStepFactory.FirstInit_TradeStep();
                myPortfolio.TradeStepPortfolio.TradeSystem = this.TradeSystem;

                myPortfolio.TradeStepPortfolio.TradeSystem.OptimizationResults = new List<IOptimizationResult>();

            }
     

            return true;
        }
        private ITradeStep FirstInitTradeStep(IDataItem myDataItem, IPortfolio myPortfolio,
            bool IsDataClass, TradeWriteModes myTradeWriteMode)
        {
            ITradeStep myTradeStep = null;
            if (IsDataClass)
            {
                myTradeStep = myDataItem.TradeStep;

            }
            else
            {
                //myTradeStep = myDataItem.TradeStep;
                myTradeStep = myPortfolio.TradeStepPortfolio;
                if (!TradeStepFactory.Reset_Portfolio_TradeStep(myPortfolio, this.tradeSystem,
                    myTradeWriteMode, false, TradeSimulation.ProgramContext.Configuration.TradeMoneyType, Intraday))
                    return null;
            }
            System.Diagnostics.Debug.Assert(myTradeStep.TradeSystem != null, "No optimization possible, the trade system is not set");
            if (myTradeStep.TradeSystem == null)
                return null;

            return myTradeStep;

        }
        public bool Optimize(IDataItem myDataItem, IPortfolio myPortfolio, bool IsDataClass, TradeWriteModes myTradeWriteMode, IGrid myGrid)
        {
            try
            {
                System.Windows.Forms.Application.DoEvents();
                FirstInit_Optimize(myDataItem, myPortfolio, IsDataClass);
                TradeSimulation.DeleteOutputFileName(myDataItem, myPortfolio);
                if (TradeSimulation.ProgramContext.Configuration.TerminateAction)
                    return false;

                ITradeStep myTradeStep = FirstInitTradeStep(myDataItem, myPortfolio,
                    IsDataClass, myTradeWriteMode);
                
                if (myTradeStep == null)
                    return false;

                

                TradeSystem ts = myTradeStep.TradeSystem as TradeSystem;
                TradeCondition[] MyTradeConditions = ts.TradeConditions;

                System.Diagnostics.Debug.Assert(MyTradeConditions != null, "No optimization possible, the trade conditions are not set");
                if (MyTradeConditions == null)
                    return false;


                OptimizeLoop(myDataItem, myPortfolio, 0, MyTradeConditions, IsDataClass, myTradeWriteMode, myGrid);

                WriteOptimResults(myDataItem, myPortfolio, IsDataClass, myTradeWriteMode, myGrid);


                return true;

            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error in optimizing " + ex.Message);
                return false;

            }
            //Write_OptimizationResults(myDataItem, myPortfolio, IsDataClass, false);
        }
        private void WriteOptimResults(IDataItem myDataItem, IPortfolio myPortfolio, bool IsDataClass, TradeWriteModes myTradeWriteMode, IGrid myGrid)
        {

            InitOptimFile_New(myDataItem, myPortfolio, IsDataClass, false);

            this.SetTradeStep(myDataItem, myPortfolio);
            optimisationResultList = this.tradeStepActive.TradeSystem.OptimizationResults;
            //optimisationResultColl.SortByKey_WhichIsFloat();
            GetSortedOptimizationList(myDataItem, myPortfolio, IsDataClass, false);


            WriteOptimizationOverall_New(false);
            CloseOptimizationFile_New();
        }
        public void Optimize(IPortfolio myPortfolio, IDataItem myDataItem, bool IsDataClass, IGrid myGrid)
        {

            TradeSimulation.ProgramContext.Logfile.WriteTimeLog(" ... Optimizing ");


            TradeWriteModes myTradeWriteModes = TradeWriteModes.EndResultShare;
            Optimize(myDataItem, myPortfolio, IsDataClass, myTradeWriteModes, myGrid);


        }
        private static void SetOptimizationResult(IDataItem myDataItem, IPortfolio myPortfolio)
        {
            ITradeStep myTradeStep = null;
            TradeSystem myTradeSystem = null; 
            if (myDataItem == null)
            {
                myTradeStep = myPortfolio.TradeStepPortfolio;
                
            }
            else
            {
                myTradeStep = myDataItem.TradeStep;
            }
            myTradeSystem = myTradeStep.TradeSystem as TradeSystem;
            try
            {
                //save data in trade system

                TradeCondition[] MyTradeCond = myTradeSystem.TradeConditions;
                OptimizationResult optRes = new OptimizationResult();
                for (int i = 0; i < MyTradeCond.GetLength(0); i++)
                {

                    double f = Convert.ToDouble(MyTradeCond[i].ThresholdValueOrIndicator);
                    optRes.ThresholdCollection.Add(f);

                    //[i]= MyTradeCond[i].ThresholdValueOrIndicator; 
                }

                optRes.PerformanceRelative = myTradeStep.PerformanceRelative;
                optRes.Performance = myTradeStep.Performance;
                optRes.PerformancePerYear_Relative = myTradeStep.PerformanceRelativePerYear;
                optRes.PerformancePerYearAverage = myTradeStep.Performance;

                for (int i = 0; i < myTradeStep.PerformancePerYearCollection.Count; i++)
                {
                    double f = Convert.ToDouble(myTradeStep.PerformancePerYearCollection[i]);
                    optRes.PerformancePerYearList.Add(f);
                }


                //Debug.WriteLine("Simulation done with Indicators " + myTradeStep.IndicatorsString + "; Performance is " + myTradeStep.Performance.ToString() + "; BuyHold is : " + myTradeStep.PerformanceBuyAndHold_Share.ToString());

                myTradeStep.TradeSystem.OptimizationResults.Add(optRes);
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error in SetOptimizationResult: " + ex.Message);
            }

        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="MyListView"></param>
        public void OptimizePortfolio_1_Overall(IPortfolio myPortfolio, IGrid myGrid)
        {


          
            if (TradeSimulation.ProgramContext.Configuration.TerminateAction)
                return;
            //myDataItem.TradeStep.Portfolio = myDataItem.TradeStep.Portfolio;


            int myNumberOfItems = 0;
            if (myPortfolio != null && myPortfolio.DataItems.Count > 0)
            {
                for(int i = 0; i < myPortfolio.DataItems.Count; i ++) 
                {
                    IDataItem dc = myPortfolio.DataItems[i];
                    if (TradeSimulation.ProgramContext.Configuration.TerminateAction)
                        return;

                    myNumberOfItems++;
                    //myDataItem.DataClass = dc.DataClass;
                    object o = dc.DataClass;
                    dc.DataClass.DeSerialize(ref o);


                }
            }

            
            for( int i = 0; i < myPortfolio.DataItems.Count; i++)
            {
                IDataItem myDataItem = myPortfolio.DataItems[i];
                if (TradeSimulation.ProgramContext.Configuration.TerminateAction)
                    return;
                myNumberOfItems++;

                ITradeStep ts = myDataItem.TradeStep;


                myDataItem.DataClass.Get_Indicators_ForTradeSystem(true, ts.TradeSystem);

                //myDataItem.DataClass = dc;

                

                Optimize(myPortfolio, myDataItem,  true, myGrid);
            }


        }

        private void OptimizeLoop(IDataItem myDataItem, IPortfolio myPortfolio, int iTradeIndex, TradeCondition[] MyTradeConditions, 
            bool IsDataClass, TradeWriteModes myTradeWriteMode, IGrid myGrid)
        {
            System.Windows.Forms.Application.DoEvents();
            if (TradeSimulation.ProgramContext.Configuration.TerminateAction)
            {
                //TradeSimulation.ProgramContext.Configuration.TerminateAction = false;
                return;
            }

            int MyArrLength = MyTradeConditions.GetLength(0);
            double[] MyOptimPars;
            MyOptimPars = new double[MyArrLength];

            Debug.Assert(MyTradeConditions[iTradeIndex].OptimizeStep != 0, "Optimize step is 0 - this leads to an infinite loop");

            if (MyTradeConditions[iTradeIndex].OptimizeStep == 0)
                return;
            for (MyOptimPars[iTradeIndex] = MyTradeConditions[iTradeIndex].OptimizeStart;
                MyOptimPars[iTradeIndex] <= MyTradeConditions[iTradeIndex].OptimizeEnd;
                MyOptimPars[iTradeIndex] += MyTradeConditions[iTradeIndex].OptimizeStep)
            {
                if (TradeSimulation.ProgramContext.Configuration.TerminateAction)
                    return;
                MyTradeConditions[iTradeIndex].ThresholdValueOrIndicator = MyOptimPars[iTradeIndex].ToString();
                int jOptim = iTradeIndex + 1;
                if (jOptim < MyArrLength)
                    OptimizeLoop(myDataItem, myPortfolio, jOptim, MyTradeConditions, IsDataClass, myTradeWriteMode, myGrid);

                if (iTradeIndex == (MyArrLength - 1))
                {
                    //now start optimizing
                    if (IsDataClass)
                    {
                        SimulationShareForOptimization(myDataItem, myTradeWriteMode, true, myGrid);
                    }
                    else
                    {
                        TradeSystemStaticFunctions.SetTradeConditionsInTradeStep(myPortfolio.TradeStepPortfolio, myPortfolio.TradeStepPortfolio.TradeSystem);
                        this.SimulationPortfolio_Individual(myPortfolio, myTradeWriteMode, myGrid, true);
                    }
                }
            }

        }
        #endregion


        #region old portfolio


        public bool SimulationPortfolio_Individual(IPortfolio myPortfolio,   TradeWriteModes myTradeMode
            , IGrid myGrid, bool inOptimizationLoop)
        {
            if (myPortfolio.DataItems.Count < 1)
            {
                System.Windows.Forms.MessageBox.Show("No data items to simulate for " + myPortfolio.Name);
                return false;
            }
            TradeSimulation.ProgramContext.Logfile.WriteTimeLog(" ... Simulate Portfolio individual");

            try
            {
                TradeStepFactory.Reset_Portfolio_TradeStep(myPortfolio, this.tradeSystem,
                    myTradeMode, false, TradeSimulation.ProgramContext.Configuration.TradeMoneyType, Intraday);
                //myDataItem.TradeStep.TradeWriteMode = myTradeMode;
                myPortfolio.TradeStepPortfolio.TradeWriteMode = myTradeMode;


                //DateTime dt = TradeSimulation.ProgramContext.Trader_Simulation.GetLastDateForPortfolio(myPortfolio);

                myPortfolio.TradeStepPortfolio.Money = 0;

                myPortfolio.TradeStepPortfolio.MaxMoneyForBuyPerPortfolio = myPortfolio.DataItems.Count * myPortfolio.TradeStepPortfolio.MaxMoneyForBuyPerShare;

                for (int i = 0; i < myPortfolio.DataItems.Count; i++)
                {
                    IDataItem myDataItem = myPortfolio.DataItems[i];
                    
                    SimulationShare(myDataItem, myTradeMode, true, false, myGrid);
                }


                //use some other end evaluation for this kind
                //TradeStepFactory.WritePortfolioTradeInList(myDataItem.TradeStep, myDataItem.TradeStepPortfolio, myGrid, true);
                //myDataItem.TradeStep.Portfolio.Serialize(TradeSimulation.ProgramContext.Configuration.Directories.PortfolioPath);
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error simulating portfolio" + ex.Message);
                return false;

            }
            ITradeStep mytradeStep = myPortfolio.TradeStepPortfolio;
            TradeStepFactory.WritePortfolioTradeInList(null, mytradeStep, this.gridTrade, true);

            Write_Simulation_CSV(null, myPortfolio, inOptimizationLoop);
            return true;
        }
        private int SetInitialPortfolioSimulationDates(IPortfolio myPortfolio, TradeWriteModes myTradeMode, bool inOptimizationStep)
        {
            
            TradeStepFactory.Reset_Portfolio_TradeStep(myPortfolio, this.tradeSystem,
               myTradeMode, inOptimizationStep, TradeSimulation.ProgramContext.Configuration.TradeMoneyType, Intraday);



            TimeSpan ts = myPortfolio.TradeStepPortfolio.DateMax - myPortfolio.TradeStepPortfolio.DateMin;
            int iMax = ts.Days;
            
            myPortfolio.TradeStepPortfolio.Date = myPortfolio.TradeStepPortfolio.DateMin;
            myPortfolio.TradeStepPortfolio.DateIndex = 0;
            return iMax;

        }
        private static bool CheckDataItem_DataAvailable(IPortfolio myPortfolio, IDataItem myDataItem)
        {
            try
            {
                //1. see if we have portfolio data for this day
                if (myDataItem.TradeStep.DateMin <= myPortfolio.TradeStepPortfolio.Date)
                {
                    if (myDataItem.TradeStep.DateMax >= myPortfolio.TradeStepPortfolio.Date)
                    {
                        myDataItem.TradeStep.Date = myPortfolio.TradeStepPortfolio.Date;
                        if (!myDataItem.TradeStep.ShareDataAvailableForCurrentDate(myPortfolio.TradeStepPortfolio.Date))
                        {
                            //there are simply no share data available for this date!
                            //Debug.Assert(false, "SW Error - dataItem dates do not fit portfolio dates");
                            return false;
                            //ol
                        }
                        else
                        {
                            //perfect ! we should have saved some time !
                            //2. even if we are in the same period - we might not have share data for this specific day (Weekend, etc.
                            if (myDataItem.TradeStep.DateIndex > -1)
                            {
                                return true;

                            }
                        }

                        //only when there are quotes for that day


                    }

                    return false;
                }
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error in CheckDataItem_DataAvailable: " + ex.Message);
                return false;
            }
            return false;

        }
        private static bool AllocateMoneyForShare(IPortfolio myPortfolio, IDataItem myDataItem)
        {
            //3. if we traded some things, add/ subtract the money in the portfolio

            myDataItem.TradeStep.Money = 0;
            //---------------------------------
            //for each share iteration ...
            //4. see if we have money left
            if (myPortfolio.TradeStepPortfolio.Money > 0)
            {

                //5. see if we already have shares of that type - if yes, do not buy
                if (myDataItem.TradeStep.NumberOfShares == 0)
                {

                    myDataItem.TradeStep.Money = myPortfolio.TradeStepPortfolio.MaxMoneyForBuyPerShare;
                    //6. if we have less money in the portfolio than 10000, allocate the whole rest for this share
                    if (myPortfolio.TradeStepPortfolio.Money < myDataItem.TradeStep.MaxMoneyForBuyPerShare)
                    {
                        myDataItem.TradeStep.Money = myPortfolio.TradeStepPortfolio.Money;

                    }
                }

            }
            return true;
        }
        private static bool EndDataItemTransactions(IPortfolio myPortfolio, IDataItem myDataItem, IGrid myGrid)
        {
            

            //subtract the money from the portfolio money
            //myPortfolio.TradeStep.Money -= myPortfolio.TradeStep.Money;

            //7. a step occurs also for sell (that means : myPortfolio.TradeStep.Money = 0;

            myDataItem.TradeStep.Money = 0;
            if (myDataItem.TradeStep.TradeType != TradeType.Nothing)
            {

                myPortfolio.TradeStepPortfolio.Money += myDataItem.TradeStep.TransactionCosts;
                myDataItem.TradeStep.TransactionCosts = 0;
                if (myPortfolio.TradeStepPortfolio.TradeWriteMode == TradeWriteModes.OnlyTrade || myPortfolio.TradeStepPortfolio.TradeWriteMode == TradeWriteModes.EachTradeStep)
                    TradeStepFactory.WritePortfolioTradeInList(myDataItem, myPortfolio.TradeStepPortfolio, myGrid, false);
            }
            else
            {
                //myPortfolio.TradeStep.Money += myPortfolio.TradeStep.Money;
            }
            myDataItem.TradeStep.DateIndex++;
            if (myDataItem.TradeStep.DateIndex > myDataItem.TradeStep.DateMaxIndex)
            {
                //possibly the date of the share for this index is larger than the maximal portfolio date
                //some general error
                //Debug.Assert(false, "Increase of trade step not correct with share " + myPortfolio.TradeStep.DataClass.Name);
                myDataItem.TradeStep.DateIndex = myDataItem.TradeStep.DateMaxIndex;
            }

            return true;
        }
        private static bool IncreaseDateIndexInPortfolioSimulation(IPortfolio myPortfolio,IGrid myGrid)
        {
            try
            {
                myPortfolio.TradeStepPortfolio.DateIndex++;
                myPortfolio.TradeStepPortfolio.Date = myPortfolio.TradeStepPortfolio.Date.AddDays(1);

                if (myPortfolio.TradeStepPortfolio.TradeWriteMode != TradeWriteModes.Nothing)
                {
                    //at finish, some increase in the dateStep occured.

                    for (int i = 0; i < myPortfolio.DataItems.Count; i++)
                    {

                        TradeStep ts1 = myPortfolio.DataItems[i].TradeStep as TradeStep;
                        ts1.DateIndex--;

                    }

                    if(myPortfolio.TradeStepPortfolio.TradeWriteMode == TradeWriteModes.EachTradeStep)
                        TradeStepFactory.WritePortfolioTradeInList(null, myPortfolio.TradeStepPortfolio, myGrid, true);
                    
                    SetOptimizationResult(null, myPortfolio);
                }
                return true;
            }
            catch(Exception ex)
            {
                Debug.Assert(false, "Error in IncreaseDateIndexInPortfolioSimulation: " + ex.Message);
                return false;
            }
        }
        public bool SimulationPortfolio_PerDate(IPortfolio myPortfolio, TradeWriteModes myTradeMode, bool inOptimizationLoop, IGrid myGrid)
        {
            
            if (myPortfolio.DataItems.Count < 1)
            {
                System.Windows.Forms.MessageBox.Show("No data items to simulate for " + myPortfolio.Name);
                return false;
            }

            try
            {

                int iMax = SetInitialPortfolioSimulationDates(myPortfolio, myTradeMode, inOptimizationLoop);
                Debug.WriteLine("Min Date is " + myPortfolio.TradeStepPortfolio.Date.ToShortDateString());

                for (int i = 0; i < iMax; i++)
                {
                    for (int j = 0; j < myPortfolio.DataItems.Count; j++)
                    {
                        IDataItem myDataItem = myPortfolio.DataItems[j];
                        if (CheckDataItem_DataAvailable(myPortfolio, myDataItem))
                        {                          
                            AllocateMoneyForShare(myPortfolio, myDataItem);
                            TradeStepFactory.StepShare(myDataItem, myGrid, Intraday);
                            EndDataItemTransactions(myPortfolio, myDataItem, myGrid);
                           
                        }
                    }
                                 
                    IncreaseDateIndexInPortfolioSimulation(myPortfolio, myGrid);

                }

                //write end result:
                TradeStepFactory.WritePortfolioTradeInList(null, myPortfolio.TradeStepPortfolio, myGrid, true);
                if (!inOptimizationLoop)
                {
                    Write_Simulation_CSV(null, myPortfolio, inOptimizationLoop);
                }
                return true;

            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error in simulating portfolio " + ex.Message);
                return false;
            }
           
            
        
        }

       

        #endregion
        #region write results


        public static void Write_TradeSystem(IDataItem myDataItem)
        {
            TradeSystem MyTradeSave = myDataItem.TradeStep.TradeSystem.Copy() as TradeSystem;
            MyTradeSave.Serialize_AsTradeResult(myDataItem.DataClass.ID);


        }
        private bool WriteSinglePerformance(IDataItem myDataItem, StreamWriter writer, PerformanceType perfType)
        {
            ITradeStep myTradeStep = myDataItem.TradeStep;

            if (myTradeStep.PerformancePerYearCollection == null)
                return false;

            System.Globalization.CultureInfo cultureInfo = CUtil.Conversions.CultureCurrent;


           
            //string perf = string.Empty;
            //string perfRel = string.Empty;
            //string perfShare = string.Empty;
            string perf = myDataItem.Name + stringDelimiter;
            string perfRel = perf;
            string perfShare = perf;

            perf += myDataItem.TradeStep.Performance + stringDelimiter;
            perfRel += myDataItem.TradeStep.PerformanceRelative + stringDelimiter;
            perfShare += myDataItem.TradeStep.PerformanceBuyAndHold_Share + stringDelimiter;

            perf += myDataItem.TradeStep.PerformancePerYear + stringDelimiter;
            perfRel += myDataItem.TradeStep.PerformanceRelativePerYear + stringDelimiter;
            perfShare += myDataItem.TradeStep.PerformanceBuyAndHold_Share_PerYear + stringDelimiter;


            for (int j = 0; j < myTradeStep.PerformancePerYearCollection.Count; j++)
            {

                string strYear = myTradeStep.PerformancePerYearCollection.Keys[j].ToString();
                //5. fill item for each year

                if (myTradeStep.PerformanceRelativePerYearCollection != null &&
                    myTradeStep.PerformanceRelativePerYearCollection[strYear] != null)
                {

                    double fperf = (double)myTradeStep.PerformancePerYearCollection[strYear];
                    double fperfRel = (double)myTradeStep.PerformanceRelativePerYearCollection[strYear];

                    double fperfShare = (double)myTradeStep.PerformanceBuyAndHoldPerYearCollection[strYear];




                    perf += fperf.ToString(cultureInfo) + stringDelimiter;
                    perfRel += fperfRel.ToString(cultureInfo) + stringDelimiter;
                    perfShare += fperfShare.ToString(cultureInfo) + stringDelimiter;


                }
                else
                {
                    perf += stringDelimiter;
                    perfRel += stringDelimiter;
                    perfShare += stringDelimiter;
                }

            }
            switch (perfType)
            {
                case PerformanceType.Normal:
                    {
                        writer.WriteLine(perf);
                        break;
                    }
                case PerformanceType.Relative:
                    {
                        writer.WriteLine(perfRel);
                        break;
                    }
                case PerformanceType.Share:
                    {
                        writer.WriteLine(perfShare);
                        break;
                    }

            }

            return true;


                    
        }
        private void WritePerformance_Line(StreamWriter writer, PerformanceType perfType, ITradeStep myTradesStep)
        {
            switch (perfType)
            {
                case PerformanceType.Normal:
                    {
                        writer.WriteLine("Performance per Year " + stringDelimiter + myTradesStep.IndicatorsString);
                        break;
                    }
                case PerformanceType.Relative:
                    {
                        writer.WriteLine("Relative Performance per Year" + stringDelimiter + myTradesStep.IndicatorsString);
                        break;
                    }
                case PerformanceType.Share:
                    {
                        writer.WriteLine("Share Performance per Year" + stringDelimiter + myTradesStep.IndicatorsString);
                        break;
                    }

            }
        }
        private void SetTradeStep(IDataItem myDataItem, IPortfolio myPortfolio)
        {
            this.tradeStepActive = null;
            if (myDataItem != null)
            {
                tradeStepActive = myDataItem.TradeStep;
            }
            else
            {
                tradeStepActive = myPortfolio.TradeStepPortfolio;
            }
            
        }
        private void WriteYearList(StreamWriter writer)
        {
            //2. fill the header	
            string perf = string.Empty;
            //string perfRel = string.Empty;
            //string perfShare = string.Empty;

            perf += "Share" + stringDelimiter + "Overall" + stringDelimiter + "perYer" + stringDelimiter;
            //perfRel = perf;
            //perfShare = perf;

            //perf += ""  + " , " ;

            for (int yearIndex = 0; yearIndex < tradeStepActive.PerformancePerYearCollection.Count; yearIndex++)
            {
                //int startYear = yearIndex + 3;
                string strYear = tradeStepActive.PerformancePerYearCollection.Keys[yearIndex];

                perf += strYear + stringDelimiter;



            }
            writer.WriteLine(perf);
        }

        private void WritePerformancePerYear(IDataItem myDataItem, IPortfolio myPortfolio, StreamWriter writer, 
            PerformanceType perfType, bool inOptimizationLoop)
        {
            //if share performance is writte - myPortfolio has to be null!
            //two empty separation lines
            SetTradeStep(myDataItem, myPortfolio);
            System.Globalization.CultureInfo cultureInfo = CUtil.Conversions.CultureCurrent;

            if (!inOptimizationLoop)
            {
                writer.WriteLine("");
                writer.WriteLine("");
                WritePerformance_Line(writer, perfType, tradeStepActive);
                WriteYearList(writer);
            }
            
            if (myDataItem != null)
            {
                WriteSinglePerformance(myDataItem, writer, perfType);
                //WriteSinglePerformance(myDataItem, writer, perfType);

            }
            else if(myPortfolio != null)
            {
                myPortfolio.TradeStepPortfolio.CreateListPerYearCollection();
                string perf = WritePortfolioPerformanceString(myPortfolio);
                //writer.WriteLine("Indicators : " + myPortfolio.TradeStepPortfolio.IndicatorsString);
                writer.WriteLine(perf);

                if (!this.TradeCSVOutputOptions.Portfolio_Optimization_OnlyPortfolio)
                {
                    for (int i = 0; i < myPortfolio.DataItems.Count; i++)
                    {
                        IDataItem di = myPortfolio.DataItems[i];
                        WriteSinglePerformance(di, writer, perfType);
                    }
                    
                    //writer.WriteLine(perf);
                }
               
            }




            //-------------------------------------------------------------------------------
            //write performance per year
            try
            {

            }

            catch (Exception exc)
            {
                Debug.Assert(false, "Could not write output file - probably the file is in use !", exc.Message);
                if (writer != null)
                    writer.Close();

            }


        }
        //private string WritePortfolioPerformanceString(IPortfolio myPortfolio, PerformanceType perfType)
        //{
        //    WriteSinglePerformance(di, writer, perfType);
        //    string perf = string.Empty;
        //    string perfRel = string.Empty;
        //    string perfShare = string.Empty;

          

            


        //}
        private string WritePortfolioPerformanceString(IPortfolio myPortfolio)
        {
            System.Globalization.CultureInfo cultureInfo = CUtil.Conversions.CultureCurrent;

            string perf = string.Empty;
            string perfRel = string.Empty;
            string perfShare = string.Empty;

            perf += "Portfolio: " + myPortfolio.Name + stringDelimiter + "Ind-s: " + myPortfolio.TradeStepPortfolio.IndicatorsString + stringDelimiter;
            perfRel += perf;
            perfShare += perf;

            perf += myPortfolio.TradeStepPortfolio.Performance + stringDelimiter;
            perfRel += myPortfolio.TradeStepPortfolio.PerformanceRelative + stringDelimiter;
            perfShare += myPortfolio.TradeStepPortfolio.PerformanceBuyAndHold_Share + stringDelimiter;

            perf += myPortfolio.TradeStepPortfolio.PerformancePerYear + stringDelimiter;
            perfRel += myPortfolio.TradeStepPortfolio.PerformanceRelativePerYear + stringDelimiter;
            perfShare += myPortfolio.TradeStepPortfolio.PerformanceBuyAndHold_Share_PerYear + stringDelimiter;

            string perfPortfolio = string.Empty;
            perfPortfolio += "Portfolio: " + myPortfolio.Name + stringDelimiter;

            for (int yearIndex = 0; yearIndex < myPortfolio.TradeStepPortfolio.PerformancePerYearCollection.Count; yearIndex++)
            {
                string strYear = myPortfolio.TradeStepPortfolio.PerformancePerYearCollection.Keys[yearIndex];

                //int yearIndex = Convert.ToInt32(strYear);

                double fperf = (double)myPortfolio.TradeStepPortfolio.PerformancePerYearCollection[strYear];
                double fperfRel = (double)myPortfolio.TradeStepPortfolio.PerformanceRelativePerYearCollection[strYear];
                double fperfShare = (double)myPortfolio.TradeStepPortfolio.PerformanceBuyAndHoldPerYearCollection[strYear];




                perf += fperf.ToString(cultureInfo) + stringDelimiter;
                perfRel += fperfRel.ToString(cultureInfo) + stringDelimiter;
                perfShare += fperfShare.ToString(cultureInfo) + stringDelimiter;
            }
            switch (this.TradeCSVOutputOptions.PerformanceType)
            {
                case PerformanceType.Normal:
                    {
                        return perf;
                        
                    }
                case PerformanceType.Relative:
                    {
                        return perfRel;
                       
                    }
                case PerformanceType.Share:
                    {
                        return perfShare;
                        
                    }
                default:
                    {
                        return perfRel;
                        
                    }

            }
            
        }
        private void WritePerformanceShare_Normal(StreamWriter writer, bool overAllPortfolios)
        {
            System.Globalization.CultureInfo cultureInfo = CUtil.Conversions.CultureCurrent;


            //System.IFormatProvider ifp 
            string columnHeader = " Indicators " + stringDelimiter + stringDelimiter + " Performance " + stringDelimiter + " Relative ";

            //Debug.WriteLine("Simulation done with Indicators " + myTradeStep.IndicatorsString + "; Performance is " + myTradeStep.Performance.ToString() + "; BuyHold is : " + myTradeStep.PerformanceBuyAndHold_Share.ToString());

            writer.WriteLine(columnHeader);
            for (int i = this.optimisationResultList.Count - 1; i >= 0; i--)
            {

                OptimizationResult optimisationResult = optimisationResultList[i] as OptimizationResult;
                string indic = string.Empty;
                if (overAllPortfolios)
                {
                    indic += ((IPortfolio)TradeSimulation.ProgramContext.Trader_Simulation.Portfolios[i]).Name + " , ";
                }
                foreach (double f in optimisationResult.ThresholdCollection)
                {
                    indic += " " + f.ToString() + stringDelimiter;
                }
                //to get a csv file out of it:
                indic += " " + optimisationResult.Performance.ToString(cultureInfo) + stringDelimiter + optimisationResult.PerformanceRelative.ToString(cultureInfo);
                //Debug.WriteLine("Simulation done with Indicators " + myTradeStep.IndicatorsString + "; Performance is " + myTradeStep.Performance.ToString() + "; BuyHold is : " + myTradeStep.PerformanceBuyAndHold_Share.ToString());

                writer.WriteLine(indic);
            }
        }
        private static string GetOptimizationFileName_1(IDataItem myDataItem, IPortfolio myPortfolio, bool IsDataClass, bool overAllPortfolios, bool isCSV)
        {
            string dirName = TradeSimulation.ProgramContext.Configuration.Directories.OptimizationOutputPath + "\\";
            string myfilename = string.Empty;
            string fileExtension = ".xls";
            if(isCSV)
                fileExtension = ".csv";
            if (!System.IO.Directory.Exists(dirName))
            {
                System.IO.Directory.CreateDirectory(dirName);
            }

            if (IsDataClass)
            {
                myfilename = dirName + myDataItem.DataClass.Name + " _ " + myDataItem.TradeStep.TradeSystem.Name + fileExtension;
            }
            else
            {
                if (overAllPortfolios)
                {
                    myfilename = dirName + "ALLPortfolios_ " + myPortfolio.TradeStepPortfolio.TradeSystem.Name + fileExtension;

                }
                else
                {
                    myfilename = dirName + myPortfolio.Name + " _ " + myPortfolio.TradeStepPortfolio.TradeSystem.Name + fileExtension;

                }

            }
           
            return myfilename;
        }
        private static string GetOptimizationFileName(IDataItem myDataItem, IPortfolio myPortfolio, bool IsDataClass, bool overAllPortfolios)
        {

            string myfilename = GetOptimizationFileName_1(myDataItem, myPortfolio, IsDataClass, overAllPortfolios, true);

        
            if (!System.IO.File.Exists(myfilename))
            {
                System.IO.FileStream f;
                try
                {
                    f = System.IO.File.Create(myfilename);
                }
                catch (Exception exc)
                {
                    //could not create file probably because the filenema contains special characters...
                    System.Diagnostics.Debug.Assert(false, "could not create file probably because the filenema contains special characters... " + myfilename, exc.Message);
                    return string.Empty;

                }
                f.Close();
            }
            return myfilename;
        }
        private void InitOptimizationCollections(IDataItem myDataItem, IPortfolio myPortfolio, bool IsDataClass)
        {
            if (IsDataClass)
            {
                optimisationResultList = myDataItem.TradeStep.TradeSystem.OptimizationResults;
            }
            else
            {
                optimisationResultList = myPortfolio.TradeStepPortfolio.TradeSystem.OptimizationResults;

            }
            
        }
        private void GetSortedOptimizationList(IDataItem myDataItem, IPortfolio myPortfolio, bool IsDataClass, bool overAllPortfolios)
        {
            InitOptimizationCollections(myDataItem, myPortfolio, IsDataClass);
            NameObjectCollection optimisationResultColl = new NameObjectCollection();
            for (int i = 0; i < optimisationResultList.Count; i++)
            {

                IOptimizationResult optimisationResult = optimisationResultList[i];
                optimisationResultColl.Add(optimisationResult.Performance, optimisationResult);
            }
            if (!overAllPortfolios)
            {

                optimisationResultColl.SortByKey_WhichIsFloat();
            }
            optimisationResultList = new List<IOptimizationResult>();
            for (int i = 0; i < optimisationResultColl.Count; i++)
            {

                IOptimizationResult optimisationResult = optimisationResultColl[i] as IOptimizationResult;
                optimisationResultList.Add(optimisationResult);
            }

         
        }
  
        private void Write_ShareTradeEvents(IDataItem myDataItem, StreamWriter writer)
        {
            Debug.Assert(myDataItem != null, "Write_ShareTradeEvents called with null DataItem");

            for (int i = 0; i < myDataItem.TradeStep.TradeEvents.Count; i++)
            {
                TradeEvent tev = myDataItem.TradeStep.TradeEvents[i] as TradeEvent;

                string line = string.Empty;

                line += " " + tev.Date.ToShortDateString() + stringDelimiter + tev.TradeType.ToString() + stringDelimiter;
                line += " " + tev.Number + stringDelimiter + tev.Quote.ToString() + stringDelimiter + tev.Number + stringDelimiter;
                line += " " + tev.Performance.ToString();

                //to get a csv file out of it:
                //indic += " " + optimisationResult.Performance.ToString(cultureInfo) + " , " + optimisationResult.PerformanceRelative.ToString(cultureInfo);
                writer.WriteLine(line);
            }
        }
        private bool InitOptimFile_New(IDataItem myDataItem, IPortfolio myPortfolio, bool IsDataClass, bool overAllPortfolios)
        {
            try
            {
                string myfilename = GetOptimizationFileName_1(myDataItem, myPortfolio, IsDataClass, overAllPortfolios, false);
                excelWriterOptimization = new CUtil.Excel.ExcelWriter();
                excelWriterOptimization.CreateFile(myfilename);
                return true;
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error in InitOptimFile_New: " + ex.Message);
                return false;
            }
        }
        private bool CloseOptimizationFile_New()
        {
            //dataTableOptimization.Rows.Add(dr);
            //---------------------------------
            
            excelWriterOptimization.GenerateWorksheet(dataTableOptimization, "Optimizations");
            excelWriterOptimization.CloseFile();
            return true;

        }
        public bool WriteOptimizationOverall_New(bool overAllPortfolios)
        {
            try
            {
                System.Globalization.CultureInfo cultureInfo = CUtil.Conversions.CultureCurrent;



                dataTableOptimization = new DataTable("Optimizations");
                //header line_
                if (this.optimisationResultList.Count == 0)
                    return false;

                IOptimizationResult optimisationResult0 = this.optimisationResultList[0];

                for (int i = 0; i < optimisationResult0.ThresholdCollection.Count; i++)
                {
                    //string str = Convert.ToString(optimisationResult0.ThresholdCollection[i]);
                    dataTableOptimization.Columns.Add("Indicator:" + i.ToString());
                }


                dataTableOptimization.Columns.Add("Performance");
                dataTableOptimization.Columns.Add("Relative");

                for (int i = 0; i < optimisationResult0.PerformancePerYearList.Count; i++)
                {
                    double f = optimisationResult0.PerformancePerYearList[i];
                    dataTableOptimization.Columns.Add("Year" + i.ToString());
                }

                //DataRow dr = dataTableOptimization.NewRow();
                for (int i = optimisationResultList.Count - 1; i >= 0; i--)
                {
                    DataRow dr = dataTableOptimization.NewRow();
                    int indRow = -1;
                    OptimizationResult optimisationResult = optimisationResultList[i] as OptimizationResult;
                    //string indic = string.Empty;
                    if (overAllPortfolios)
                    {
                        indRow++;
                        dr[indRow] = ((IPortfolio)TradeSimulation.ProgramContext.Trader_Simulation.Portfolios[i]).Name;
                    }
                    foreach (double f in optimisationResult.ThresholdCollection)
                    {
                        indRow++;
                        dr[indRow] = f.ToString(cultureInfo);

                    }
                    indRow++;
                    dr[indRow] = optimisationResult.Performance.ToString(cultureInfo);
                    indRow++;
                    dr[indRow] = optimisationResult.PerformanceRelative.ToString(cultureInfo);
                    foreach (double f in optimisationResult.PerformancePerYearList)
                    {
                        indRow++;
                        dr[indRow] = f.ToString(cultureInfo);

                    }
                    dataTableOptimization.Rows.Add(dr);

                }






                return true;
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error in writing optim results " + ex.Message);
                return false;
            }



        }
        private static string CreateOutputFileNameString(IDataItem myDataItem, IPortfolio myPortfolio)
        {
            string myfilename = string.Empty;
            myfilename = TradeSimulation.ProgramContext.Configuration.Directories.TradeSystemsTemplatesPath + "\\";
            ITradeStep tsOld = null;

            ITradeStep myTradeStep = null;
            if (myDataItem != null)
            {
                myTradeStep = myDataItem.TradeStep;
                myfilename += myDataItem.DataClass.Name + " _ " + myTradeStep.TradeSystem.Name + ".csv";
                tsOld = myTradeStep;
            }
            else
            {
                myTradeStep = myPortfolio.TradeStepPortfolio;
                myfilename += myPortfolio.Name + " _ " + myTradeStep.TradeSystem.Name + ".csv";
            }
            return myfilename;

        }
        public static bool DeleteOutputFileName(IDataItem myDataItem, IPortfolio myPortfolio)
        {
            string myfilename = CreateOutputFileNameString(myDataItem, myPortfolio);
            System.IO.File.Delete(myfilename);
            return true;


        }
        public bool Write_Simulation_CSV(IDataItem myDataItem,
            IPortfolio myPortfolio, bool inOptimizationLoop)
        {
            try
            {
                string myfilename = CreateOutputFileNameString(myDataItem, myPortfolio);

                StreamWriter writer = OpenOutputFile(myfilename, inOptimizationLoop);
                if (writer == null)
                    return false;
                if (myDataItem != null)
                {
                    Write_ShareTradeEvents(myDataItem, writer);

                }
                if (writer != null)
                {
                    WritePerformancePerYear(myDataItem, myPortfolio, writer,
                        this.TradeCSVOutputOptions.PerformanceType, inOptimizationLoop);
                    writer.Close();
                }

            
                return true;
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error in Write_Simulation_CSV: " + ex.Message);
                return false;
            }
        }
      
        private static StreamWriter OpenOutputFile(string myfilename, bool append)
        {
            if (!System.IO.File.Exists(myfilename))
            {
                System.IO.FileStream f;
                try
                {
                    f = System.IO.File.Create(myfilename);
                }
                catch (Exception exc)
                {
                    //could not create file probably because the filenema contains special characters...
                    System.Diagnostics.Debug.Assert(false, "could not create file probably because the filenema contains special characters... " + myfilename, exc.Message);
                    return null;

                }
                f.Close();
            }
            StreamWriter writer = null;
            try
            {

                writer = new StreamWriter(myfilename, append);
                //System.IFormatProvider ifp 

                


            }
            catch (Exception exc)
            {
                Debug.Assert(false, "Could not write output file - probably the file is in use !", exc.Message);

                if (writer != null)
                    writer.Close();
                return null;

            }
            return writer;

        }
        #endregion


        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public ITradeSystem TradeSystem
        {
            get
            {
                if (tradeSystem == null)
                {

                    System.Collections.ArrayList tsys = CStock.TradeSystem.GetTradeSystemTemplates();
                    if (tsys != null && tsys.Count > 0)
                        tradeSystem = tsys[0] as TradeSystem;
                    //Debug.Assert(tsys != null && tsys.Count > 0);

                }

                return tradeSystem as TradeSystem;
            }
            set
            {

                ////reset indicators if the tradeSystem system has changed
                //if (value != null && tradeSystem != value)
                //{
                //    if (this.tradeSimulation != null)
                //    {
                //        ITradeSimulation ts = this.tradeSimulation as ITradeSimulation;
                //        ts.ResetIndicators();
                //    }
                //}

                tradeSystem = value;

            }
        }


        /// <summary>
        /// dataholder - the main source of data
        /// </summary>
        public static IProgramContext ProgramContext
        {
            get
            {
                if (programContext == null)
                {
                    programContext = CStock.ProgramContext.Instance;
                }
                return programContext;
            
            }
           
        }
        public bool SetTradeSystem(string filename)
        {
            ITradeSystem ts = CStock.TradeSystem.GetTradeSystemTemplate(CStock.ProgramContext.Instance.Configuration.Directories.TradeSystemsTemplatesPath + "\\" + filename + ".xml");

            if (ts != null)
            {
                tradeSystem = ts;
                return true;


            }
            return false;

        }
        public bool SetDefaultTradeSystemForShortSell()
        {
            try
            {
                SetTradeSystemForShortSellDefault();

                string filename = CUtil.TradeSystemFiles.Trade.ToString();
                return SetTradeSystem(filename);
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error in setting TradeSystem for Short sell" + ex.Message);
                return false;
            }


        }
        private bool CreateDefaultTradeSystem()
        {
            System.Collections.ArrayList arrL = CStock.TradeSystem.GetTradeSystemTemplates();
            if (arrL != null && arrL.Count > 0)
            {
                tradeSystem = arrL[0] as TradeSystem;
                programContext.TradeEconomy.TradeSystemName = tradeSystem.ID;
            }
            else
            {
                TradeSystemFactory tsf = new TradeSystemFactory();
                tsf.Create_Default();
                tradeSystem = tsf.StockObjectBase as TradeSystem;
                tradeSystem.Serialize();
                programContext.TradeEconomy.TradeSystemName = tradeSystem.ID;
                //System.Windows.Forms.MessageBox.Show("No tradesystem available - please reinstall or create one");
                return false;

            }
            return true;
        }
        public bool SetDefaultTradeSystem()
        {
            try
            {
                string shortFileName = ProgramContext.TradeEconomy.TradeSystemName;
                if (String.IsNullOrEmpty(shortFileName) )
                {
                    return CreateDefaultTradeSystem();

                }
                else
                {
                    ITradeSystem ts = CStock.TradeSystem.GetTradeSystemTemplate(ProgramContext.Configuration.Directories.TradeSystemsTemplatesPath + "\\" + shortFileName + ".xml");
                    this.tradeSystem = ts;
                    if (ts != null)
                    {
                        programContext.TradeEconomy.TradeSystemName = tradeSystem.ID;
                        return true;
                    }
                    else
                    {
                        return CreateDefaultTradeSystem();
                    }
                }
                
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error is setting default trade system " + ex.Message);
                return false;
            }
        }
        private static bool SetTradeSystemForShortSellDefault()
        {
            string filename = CUtil.TradeSystemFiles.TradeShortSell.ToString();
            ITradeSystem ts = CStock.TradeSystem.GetTradeSystemTemplate(CStock.ProgramContext.Instance.Configuration.Directories.TradeSystemsTemplatesPath + "\\" + filename + ".xml");

            if (ts != null)
            {
                tradeSystemForShortSell = ts;

                return true;
            }
            return false;

        }
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public ITradeSystem TradeSystemForShortSell
        {
            get
            {
                return tradeSystemForShortSell;
            }
            set
            {
                tradeSystemForShortSell = value;
            }
        }

        public bool RefreshTradeSystemIndicator(IDataClass dc, ITradeSystem ts, bool forceRefresh)
        {
            try
            {
                if (dc.TradeSystemIndicator == null || forceRefresh)
                {
                    //perhaps ask first if is available or put a variable ForceRefresh

                    IIndicator ind = new Indicator();
                    ind.Parent = dc;

                    ind.Evaluate_ForTradeSystem(ts, dc, CStock.ProgramContext.Instance.Configuration.TradeMoneyType);

                    dc.TradeSystemIndicator = ind;

                    return true;



                }
            }
            catch (Exception exc)
            {
                Debug.Assert(false, "Error calculating tradeSystemSystem Indicator", exc.Message);
                return false;
            }
            return false;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public bool SetTradeOrders()
        {
            //get TradeSystem
            // make decisions
            // add orders
            // fill OrderList
            //1. get current date
            
            DateTime dt = CStock.ProgramContext.Instance.TradeEconomy.Date_Current;

            //2. See the order list - if there is money left for additional orders

            double val = this.trader.Orders.Value_Orders(dt);
            //if there is some money left, add some order ...
            if (val < this.trader.Money_Current)
            {
                Debug.Assert(tradeSystem != null);
                //tradeSystem.

            }
            return true;
            //throw new Exception("The method or operation is not implemented.");
        }
        private static void TradeSystem_Decide()
        {
        }
  
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public static System.Collections.ArrayList TradeSystemsAvailable
        {
            get
            {
                if (tradeSystems == null)
                {

                    tradeSystems = CStock.TradeSystem.GetTradeSystemTemplates();
                }
                return tradeSystems;
            }
        }

    }


    public enum PerformanceType
    {
        Relative,
        Normal,
        Share
    }

}


